#!/bin/bash
CUR_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
TOP_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../" &> /dev/null && pwd )"

pyellow() {
  echo -e "\033[33m $1 \033[0m"
}
ymlToVar() {
  eval $(yq -o=shell $1)
  #export $(yq e -o props $1 | grep -vE "^[[:space:]]*#|^[[:space:]]*$" | awk -F ' = ' '{gsub(/\./, "_", $1); print $1"="$2}')
}

get_interface_for_ip() {
    echo $(ip route get fibmatch $1 | grep -v "via" |awk '{print $3}')
}
get_srcip_for_ip() {
    echo $(ip route get fibmatch $1 | grep -v "default" | sed 's/.* src //' | awk '{print $1}')
}

variable_expansion() {
    local srcYaml=$1
    local targetYaml=$2
    local vars=$3
    [ -n "$vars" ] && eval "$vars"
    eval $(yq -o=shell $srcYaml | xargs -I {} echo {})
    eval "cat <<EOF
$(< $srcYaml)
EOF" > $targetYaml
}

get_cgroupdriver() {
  local plat=$(uname -m)
  case $plat in
    x86_64|aarch64) echo "systemd" ;;
    mips64el|mips64le|mips64) echo "cgroupfs" ;;
    *) echo "unknown plat" ;;
  esac
}

get_dev_ipMask() {
  echo $(ip -f inet -o addr show dev $1 | grep brd | awk -F ' ' '{print $4}')
}
get_default_dev() {
  echo $(ip route list | grep default | grep -oE "dev [^ ]{1,}"| awk -F ' ' '{print $2}')
}

get_docker_version() {
  case $K8S_version.yaml in
    1.22*|1.21*) echo "20.10.24"
      ;;
    1.20*|1.19*|1.18*|1.17*) echo "19.03.15"
      ;;
    *) echo "20.10.24" 
      ;;
  esac
}

get_cri_version() {
  case $K8S_cri in
    docker)
      get_docker_version
      ;;
  esac 
}


edit_k8s_config() {
    local k8s_config_file=$1
    if [ -f $CUR_DIR/k8s.conf ]; then
        ymlToVar $CUR_DIR/k8s.conf
        local keys=$(yq eval '.K8S|keys|.[]' $CUR_DIR/k8s.conf)
        local var=""
        for i in $keys; do
            var=K8S_$i
            if [ -n "${!var}" ]; then
                yq -i .K8S.$i=\"${!var}\" $k8s_config_file
            fi
        done
    fi

    if [ -n "$K8S_version" ]; then
        yq -i .K8S.version=\"$K8S_version\" $k8s_config_file
    else
        local k8sVersion=$(yq .K8S.version $k8s_config_file)
        if [ -z "$k8sVersion" ] || [ "null" == "$k8sVersion" ]; then
            yq -i .K8S.version=\"1.21.11\" $k8s_config_file
        fi
    fi
	
    if [ -n "$K8S_startNow" ]; then
        yq -i .K8S.startNow=\"$K8S_startNow\" $k8s_config_file
    else
        local start=$(yq .K8S.startNow $k8s_config_file)
        if [ -z "$start" ] || [ "null" == "$start" ]; then
            yq -i .K8S.startNow=\"false\" $k8s_config_file
        fi
    fi

	if [ -n "$K8S_criSocket" ]; then
        yq -i .K8S.criSocket=\"$K8S_criSocket\" $k8s_config_file
    else
        local sock=$(yq .K8S.criSocket $k8s_config_file)
        if [ -z "$sock" ] || [ "null" == "$sock" ]; then
		    local cri=$(yq .K8S.cri $k8s_config_file)
		    if [ $cri == "docker" ]; then
			    sock="/var/run/dockershim.sock"
			elif [ $cri == "containerd" ]; then
			    sock="/run/containerd/containerd.sock"
			fi
            yq -i .K8S.criSocket=\"${sock}\" $k8s_config_file
        fi
    fi
    if [ -n "$K8S_cgroupDriver" ]; then
        yq -i .K8S.cgroupDriver=\"$K8S_cgroupDriver\" $k8s_config_file
    else
        local drv=$(yq .K8S.cgroupDriver $k8s_config_file)
        if [ -z "$drv" ] || [ "null" == "$drv" ]; then
            yq -i .K8S.cgroupDriver=\"$(get_cgroupdriver)\" $k8s_config_file
        fi
    fi

    if [ -n "$K8S_anonymousAuth" ]; then
        yq -i .K8S.anonymousAuth=\"$K8S_anonymousAuth\" $k8s_config_file
    else
        local auth=$(yq .K8S.anonymousAuth $k8s_config_file)
        if [ -z "$auth" ] || [ "null" == "$auth" ]; then
            yq -i .K8S.anonymousAuth=\"false\" $k8s_config_file
        fi
    fi
    yq -i .K8S.nodePkgPath=\"${TOP_DIR}\" $k8s_config_file

	if [ -n "$K8S_mode" ]; then
        yq -i .K8S.mode=\"$K8S_mode\" $k8s_config_file
    else
        local mode=$(yq .K8S.mode $k8s_config_file)
        if [ -z "$mode" ] || [ "null" == "$mode" ]; then
            mode="standard"
            yq -i .K8S.mode=\"$mode\" $k8s_config_file
        fi
    fi
	
    if [ -n "$K8S_ha" ]; then
        yq -i .K8S.ha=\"$K8S_ha\" $k8s_config_file
    else
        local ha=$(yq .K8S.ha $k8s_config_file)
        if [ -z "$ha" ] || [ "null" == "$ha" ]; then
            ha="false"
            yq -i .K8S.ha=\"$ha\" $k8s_config_file
        fi
    fi
	
	if [ -n "$K8S_vipEnable" ]; then
        yq -i .K8S.vipEnable=\"$K8S_vipEnable\" $k8s_config_file
    else
	    ha=$(yq .K8S.ha $k8s_config_file)
        local vipEnable=$(yq .K8S.vipEnable $k8s_config_file)
        if [ -z "$vipEnable" ] || [ "null" == "$vipEnable" ] || [ "false" == "$vipEnable" ]; then
			if [ "$ha" == "true" ]; then
                vipEnable=true
			else
			    vipEnable=false
			fi
			yq -i .K8S.vipEnable=\"$vipEnable\" $k8s_config_file
        fi
    fi

    if [ -n "$K8S_sandbox" ]; then
        yq -i .K8S.sandbox=\"$K8S_sandbox\" $k8s_config_file
    else
        local sandbox=$(yq .K8S.sandbox $k8s_config_file)
        if [ -z "$sandbox" ] || [ "null" == "$sandbox" ]; then
            sandbox=$(cat $TOP_DIR/images/image-${K8S_version}.txt | grep "/pause:" | grep -vE "^#|^\[ \\t\]\*#")
            yq -i .K8S.sandbox=\"$sandbox\" $k8s_config_file
        fi
    fi

    return
}


# 将命令行参数和etc原配置进行merge
# 如果命令行配置和etc原配置冲突，则修改，以命令行参数为准
# 如果命令行没有配置，则保留etc原配置
# 如果没有配置，则生成默认配置
edit_node_config() {
    local node_config_file=$1
    if [ -f $CUR_DIR/node.yaml ]; then
        ymlToVar $CUR_DIR/node.yaml
        local keys=$(yq eval '.NODE|keys|.[]' $CUR_DIR/node.yaml)
        local var=""
        for i in $keys; do
            var=NODE_$i
            if [ -n "${!var}" ]; then
                yq -i .NODE.$i=\"${!var}\" $node_config_file
            fi
        done
    fi

    if [ -n "$NODE_hostname" ]; then
        yq -i .NODE.hostname=\"$NODE_hostname\" $node_config_file
    else
        local hostname=$(yq .NODE.hostname $node_config_file)
        if [ -z "$hostname" ] || [ "null" == "$hostname" ] ; then
            yq -i .NODE.hostname=\"$(hostname)\" $node_config_file
        fi
    fi

    if [ -n "$NODE_mode" ]; then
        yq -i .NODE.mode=\"$NODE_mode\" $node_config_file
    else
        local mode=$(yq .NODE.mode $node_config_file)
        if [ -z "$mode" ] || [ "null" == "$mode" ]; then
            yq -i .NODE.mode=\"create\" $node_config_file
        fi
    fi
    if [ -n "$NODE_clusterRole" ]; then
        yq -i .NODE.clusterRole=\"$NODE_clusterRole\" $node_config_file
    else
        local clusterRole=$(yq .NODE.clusterRole $node_config_file)
        if [ -z "$clusterRole" ] || [ "null" == "$clusterRole" ]; then
            if $(yq '.NODE.mode == "create"' $node_config_file) ; then
                clusterRole="controlPlane"
            else
                clusterRole="worker"
            fi
            yq -i .NODE.clusterRole=\"$clusterRole\" $node_config_file
        fi
    fi

    if [ -n "$NODE_mgmtInterface" ]; then
        yq -i .NODE.mgmtInterface=\"$NODE_mgmtInterface\" $node_config_file
    else
        local mif=$(yq .NODE.mgmtInterface $node_config_file)
        if [ -z "$mif" ] || [ "null" == "$mif" ]; then
            yq -i .NODE.mgmtInterface=\"$(get_default_dev)\" $node_config_file
        fi
    fi

    if [ -n "$NODE_mgmtIpaddress" ]; then
        yq -i .NODE.mgmtIpaddress=\"$NODE_mgmtIpaddress\" $node_config_file
    else
        local mip=$(yq .NODE.mgmtIpaddress $node_config_file)
        if [ -z "$mip" ] || [ "null" == "$(yq .NODE.mgmtIpaddress $node_config_file)" ]; then
            local dev=$(yq .NODE.mgmtInterface $node_config_file)
            yq -i .NODE.mgmtIpaddress=\"$(get_dev_ipMask $dev)\" $node_config_file
        fi
    fi

    if [ -n "$NODE_internalInterface" ]; then
        yq -i .NODE.internalInterface=\"$NODE_internalInterface\" $node_config_file
    else
        local iif=$(yq .NODE.internalInterface $node_config_file)
        if [ -z "$iif" ] || [ "null" == "$iif" ]; then
            iif=$(yq .NODE.mgmtInterface $node_config_file)
            yq -i .NODE.internalInterface=\"$iif\" $node_config_file
        fi
    fi

    if [ -n "$NODE_vip" ]; then
        yq -i .NODE.vip=\"$NODE_vip\" $node_config_file
    fi
    if [ -n "$NODE_vipInterface" ]; then
        yq -i .NODE.vipInterface=\"$NODE_vipInterface\" $node_config_file
    else
        local vif=$(yq .NODE.vipInterface $node_config_file)
        if [ -z "$vif" ] || [ "null" == "$vif" ]; then
		    vip=$(yq .NODE.vip $node_config_file)
		    if [ -n "$vip" ] && [ "$vip" != "null" ] ; then
			    vif=$(get_interface_for_ip $vip)
			else
			    vif=$(yq .NODE.mgmtInterface $node_config_file)
			fi
            yq -i .NODE.vipInterface=\"$vif\" $node_config_file
        fi
    fi
	
	if [ -n "$NODE_internalIP" ]; then
        yq -i .NODE.internalIP=\"$NODE_internalIP\" $node_config_file
    else
        local cip=$(yq .NODE.internalIP $node_config_file)
        if [ -z "$cip" ] || [ "null" == "$cip" ]; then
		    vip=$(yq .NODE.vip $node_config_file)
		    if [ -n "$vip" ] && [ "$vip" != "null" ] ; then
			    cip=$(get_srcip_for_ip $vip)
			else
			    cip=$(yq .NODE.mgmtIpaddress $node_config_file)
			fi
            yq -i .NODE.internalIP=\"$cip\" $node_config_file
        fi
    fi

    if [ -n "$NODE_manageIP" ]; then
        yq -i .NODE.manageIP=\"$NODE_manageIP\" $node_config_file
    else
        local mip=$(yq .NODE.manageIP $node_config_file)
        if [ -z "$mip" ] || [ "null" == "$mip" ]; then
            local saddr=$(yq .NODE.mgmtIpaddress $node_config_file)
            yq -i .NODE.manageIP=\"${saddr%/*}\" $node_config_file
        fi
    fi
    if [ -n "$NODE_imageRegistryIP" ]; then
        yq -i .NODE.imageRegistryIP=\"$NODE_imageRegistryIP\" $node_config_file
    else
        local imrip=$(yq .NODE.imageRegistryIP $node_config_file)
        if [ -z "$imrip" ] || [ "null" == "$imrip" ]; then
            local addr=$(yq .NODE.manageIP $node_config_file)
            yq -i .NODE.imageRegistryIP=\"${addr%/*}\" $node_config_file
        fi
    fi
}


##==MAIN()==================================================================
if [ -z $1 ]; then
    pkgYaml=$CUR_DIR/config/package-1.21.11.yaml
else
    pkgYaml=$1
fi
DOWNLOAD_ONLY=${DOWNLOAD_ONLY:-false}
# var
eval $(yq -o=shell  $pkgYaml)
variable_expansion $CUR_DIR/template/download.yaml.tmpl $CUR_DIR/download.yaml

rm -rf $TOP_DIR/config/globalVars
cat >> $TOP_DIR/config/globalVars << EOF
#!/bin/bash
$(yq -o=shell $pkgYaml)
$(yq -o=shell $CUR_DIR/download.yaml)
EOF
chmod +x $TOP_DIR/config/globalVars

if $DOWNLOAD_ONLY ; then
    exit 0
fi

if [ -f $CUR_DIR/k8s.conf ]; then
    if [ "true" == $(yq '.K8S | has("vkeConfigPath")' $CUR_DIR/k8s.conf) ]; then
        K8S_vkeConfigPath=${K8S_vkeConfigPath:-$(yq .K8S.vkeConfigPath $CUR_DIR/k8s.conf)}
    fi
    if [ "true" == $(yq '.K8S | has("vkeLibPath")' $CUR_DIR/k8s.conf) ]; then
        K8S_vkeLibPath=${K8S_vkeLibPath:-$(yq .K8S.vkeLibPath $CUR_DIR/k8s.conf)}
    fi
	if [ "true" == $(yq '.K8S | has("vkeVarPath")' $CUR_DIR/k8s.conf) ]; then
        K8S_vkeVarPath=${K8S_vkeVarPath:-$(yq .K8S.vkeVarPath $CUR_DIR/k8s.conf)}
    fi
fi
K8S_vkeConfigPath=${K8S_vkeConfigPath:-$(yq .K8S.vkeConfigPath $CUR_DIR/template/k8s.conf.tmpl)}
K8S_vkeLibPath=${K8S_vkeLibPath:-$(yq .K8S.vkeLibPath $CUR_DIR/template/k8s.conf.tmpl)}
K8S_vkeVarPath=${K8S_vkeVarPath:-$(yq .K8S.vkeVarPath $CUR_DIR/template/k8s.conf.tmpl)}


mkdir -p $K8S_vkeConfigPath
mkdir -p $K8S_vkeLibPath
mkdir -p $K8S_vkeVarPath

# etc 配置
NODECONF=${NODECONF:-$K8S_vkeConfigPath/node.yaml}
K8SCONF=${K8SCONF:-$K8S_vkeConfigPath/k8s.conf}

cp -rf $CUR_DIR/template/node.yaml.tmpl $NODECONF
edit_node_config $NODECONF

cp -rf $CUR_DIR/template/k8s.conf.tmpl $K8SCONF
edit_k8s_config  $K8SCONF

cp -rf $CUR_DIR/template/init-k8s.yaml.tmpl $K8S_vkeConfigPath/
cp -rf $CUR_DIR/etc/audit-policy.yaml $K8S_vkeConfigPath/
cp -rf $CUR_DIR/etc/roles.yaml $K8S_vkeConfigPath/
cp -rf $pkgYaml $K8S_vkeConfigPath/


# lib
cp -rf $TOP_DIR/scripts/utils.sh $K8S_vkeLibPath/



cat >> $TOP_DIR/config/globalVars << EOF
$(yq -o=shell $K8SCONF)
$(yq -o=shell $NODECONF)
EOF
chmod +x $TOP_DIR/config/globalVars
#cp -rf $TOP_DIR/globalVars $K8S_vkeLibPath/



